﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AppSocketModel;
using AppSocketService;
using AppSocketService.Account;
using BCGPSCommon;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace BCGPSRESTful
{
    /// <inheritdoc/>
    public class WebContextService : IApplicationContextService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;

        private AccountDto account;

        // 此构造函数不建议添加我们的接口，否则可能会造成循环依赖问题。
        // 作为替代方案，可以使用 _httpContextAccessor.HttpContext.RequestServices 获取所需要的服务。
        public WebContextService(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public IServiceProvider RequestServices
        {
            get
            {
                return _httpContextAccessor.HttpContext.RequestServices;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public AccountDto Account
        {
            get
            {
                if (this.account == null)
                {
                    this.ResolveUser();
                }

                return this.account;
            }
        }

        public string IPAddress
        {
            get
            {
                var userHostAddress = _httpContextAccessor.HttpContext?.Request?.Headers["X-Forwarded-For"].FirstOrDefault();

                if (string.IsNullOrEmpty(userHostAddress))
                {
                    userHostAddress = _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
                }

                return IPHelper.RemovePortNumber(userHostAddress);
            }
        }

        private void ResolveUser()
        {
            if (_httpContextAccessor.HttpContext.User.Identity.IsAuthenticated && _httpContextAccessor.HttpContext.User.Identity.Name.StartsWith("AccountCode:"))
            {
                string accountCode = _httpContextAccessor.HttpContext.User.Identity.Name.Replace("AccountCode:", "");

                IAccountService accountService = _httpContextAccessor.HttpContext.RequestServices.GetService<IAccountService>();

                this.account = accountService.GetAccount(accountCode);

                if (this.account == null)
                {
                    throw new ArgumentException("登录账户不存在!");
                }
            }
            else
            {
                throw new ArgumentException("意外的错误2!");
            }
        }
    }
}
